import { toUpper, isObject } from 'lodash';
import JqComponent, { listenProps, setGlobalComponent, removeGlobalComponent } from './JqComponent';
import router, { setRouters } from './router';
import { COMPONENT_ID } from './const';
import md5 from 'js-md5';

export const useJquery = jQuery => {

  function findInnerComponents($dom) {
    return $dom.find(`[${COMPONENT_ID}]`);
  }
  
  function broadcastDestroyComponents($dom) {
    const $domComponents = findInnerComponents($dom);
    $domComponents.each((index, dom) => {
      const componentId = jQuery(dom).attr(COMPONENT_ID);
      listenProps.emit(componentId, 'destroy', { componentId, dom });
    })
  }

  const $html = jQuery.prototype.html;
  const $attr = jQuery.prototype.attr;
  const $data = jQuery.prototype.data;

  jQuery.component = function (tagName, conf) {
    return setGlobalComponent(toUpper(tagName), conf);
  };

  jQuery.unComponent = function(tagName) {
    return removeGlobalComponent(toUpper(tagName))
  }

  jQuery.router = function (routers, tagName = 'router-view') {
    setRouters(routers);
    jQuery.component(tagName, router);
  }

  jQuery.prototype.attr = function () {
    let args = [...arguments];
    let [key, val] = args;
    let componentId = $attr.call(this, COMPONENT_ID);
    if (componentId) {
      listenProps.emit(componentId, key, val);
    }
    return $attr.apply(this, args);
  }

  jQuery.prototype.data = function () {
    let args = [...arguments];
    let [key, val] = args;
    let componentId = $attr.call(this, COMPONENT_ID);
    if (componentId) {
      listenProps.emit(componentId, key, val);
    }
    return $data.apply(this, args)
  }

  jQuery.prototype.html = function (obj) {
    // 通知销毁组件
    broadcastDestroyComponents(this);
    if (isObject(obj)) {
      // 在根节点下动态生成一个占位组件标签
      const templateApp = 'template-' + md5(JSON.stringify(obj));
      $html.call(this, `<${templateApp}></${templateApp}>`);
      // 注册这个组件
      jQuery.component(templateApp, obj);
      // 则生成组件实例，再渲染
      let jqc = new JqComponent(obj);
      jqc.render(this.get(0))
      // 销毁动态组件
      jQuery.unComponent(templateApp);
      return this;
    } else {
      return $html.call(this, obj)
    }
  }
};